#ifndef CCAMERA_H_
#define CCAMERA_H_
#include "MMath.h"

class CCamera
{
private:
	
	CCamera() { Reset(); }
	~CCamera() { }
public:
	Mat4		m_CamMat;

	static CCamera *GetInstance()
	{
		static CCamera Instance;
		return &Instance;
	}

	void SetPosition(float fX, float fY, float fZ) { m_CamMat.waxis.x = fX; m_CamMat.waxis.y = fY; m_CamMat.waxis.z = fZ; }
	void SetPosition(Vec3& vPosition) { SetPosition(vPosition.x, vPosition.y, vPosition.z); }
	const Vec3& GetSide() { return m_CamMat.xaxis; }
	const Vec3& GetUp() { return m_CamMat.yaxis; }
	const Vec3& GetForward() { return m_CamMat.zaxis; }
	const Vec3& GetPosition() { return m_CamMat.waxis; }
	const Mat4& GetInternalMatrix() { return m_CamMat; }
	Mat4 GetCameraMatrix();

	void Reset() { m_CamMat.MakeIdentity(); }
	void ApplyCameraMatrix();
	void OrthoNormalize();
	void LookAt(float fX, float fY, float fZ) { LookAt(Vec3(fX, fY, fZ)); }
	void LookAt(Vec3& vPoint);
	void Attach(Vec3& vPoint, Vec3& vOffset);

	void TranslateLocalX(float fDelta);
	void TranslateLocalY(float fDelta);
	void TranslateLocalZ(float fDelta);
	void TranslateLocal(float fX, float fY, float fZ);
	void TranslateLocal(Vec3& vDelta) { TranslateLocal(vDelta.x, vDelta.y, vDelta.z); }

	void RotateLocalX(float fDelta);
	void RotateLocalY(float fDelta);
	void RotateLocalZ(float fDelta);
	void RotateLocal(float fDelta, float fX, float fY, float fZ) { RotateLocal(fDelta, Vec3(fX, fY, fZ)); }
	void RotateLocal(float fDelta, Vec3& vAxis);

	void TranslateGlobalX(float fDelta);
	void TranslateGlobalY(float fDelta);
	void TranslateGlobalZ(float fDelta);
	void TranslateGlobal(float fX, float fY, float fZ) { TranslateGlobal(Vec3(fX, fY, fZ)); }
	void TranslateGlobal(Vec3& vDelta);

	void RotateGlobalX(float fDelta);
	void RotateGlobalY(float fDelta);
	void RotateGlobalZ(float fDelta);
	void RotateGlobal(float fDelta, float fX, float fY, float fZ) { RotateGlobal(fDelta, Vec3(fX, fY, fZ)); }
	void RotateGlobal(float fDelta, Vec3& vAxis);
};

#endif